﻿/*************************************
// Copyright (c) 2018 hanlilong,All rights reserved.
// Author:hanlilong
// Created:2023-03-17 16:18:53
// Email:hanlilong2004@163.com
// Description:
**************************************/

using System.Drawing.Drawing2D;
using System.Drawing;
using System.Windows.Forms;
using System;

namespace YonYou.U8.IN.Forms
{
    public abstract class AbstractStyleProvider : IStyleProvider
    {
        public Color DisableForeColor
        {
            get
            {
                return this._DisableForeColor;
            }
            set
            {
                this._DisableForeColor = value;
            }
        }

        public void Draw(PaintEventArgs e, ButtonEx button)
        {
            this.OnDraw(e.Graphics, e.ClipRectangle, button);
        }

        protected abstract void OnDraw(Graphics g, Rectangle clientRect, ButtonEx button);

        protected void RenderBackground(Graphics g, Rectangle rect, Color backColor, Color borderColor, bool drawBorder)
        {
            if (drawBorder)
            {
                rect.Inflate(-1, -1);
            }
            using (Brush brush = new SolidBrush(backColor))
            {
                g.FillRectangle(brush, rect);
                if (drawBorder)
                {
                    using (Pen pen = new Pen(borderColor))
                    {
                        g.DrawRectangle(pen, rect);
                    }
                }
            }
        }

        protected void RenderBackground(Graphics g, Rectangle rect, Color backColor, Color borderColor, Color innerBorderColor, RoundStyle style, int roundWidth, float basePosition, bool drawBorder, LinearGradientMode mode)
        {
            if (drawBorder)
            {
                rect.Inflate(-1, -1);
            }
            using (LinearGradientBrush linearGradientBrush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, mode))
            {
                Color[] colors = new Color[]
                {
                    backColor,
                    backColor,
                    backColor,
                    backColor
                };
                linearGradientBrush.InterpolationColors = new ColorBlend
                {
                    Positions = new float[]
                    {
                        0f,
                        basePosition,
                        basePosition + 0.05f,
                        1f
                    },
                    Colors = colors
                };
                if (style != RoundStyle.None)
                {
                    using (GraphicsPath graphicsPath = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
                    {
                        g.FillPath(linearGradientBrush, graphicsPath);
                    }
                    if (backColor.A > 80)
                    {
                        Rectangle rect2 = rect;
                        if (mode == LinearGradientMode.Vertical)
                        {
                            rect2.Height = (int)((float)rect2.Height * basePosition);
                        }
                        else
                        {
                            rect2.Width = (int)((float)rect.Width * basePosition);
                        }
                        using (GraphicsPath graphicsPath2 = GraphicsPathHelper.CreatePath(rect2, roundWidth, RoundStyle.Top, false))
                        {
                            using (SolidBrush solidBrush = new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
                            {
                                g.FillPath(solidBrush, graphicsPath2);
                            }
                        }
                    }
                    if (drawBorder)
                    {
                        using (GraphicsPath graphicsPath = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
                        {
                            using (Pen pen = new Pen(borderColor))
                            {
                                g.DrawPath(pen, graphicsPath);
                            }
                        }
                        rect.Inflate(-1, -1);
                        using (GraphicsPath graphicsPath = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
                        {
                            using (Pen pen = new Pen(innerBorderColor))
                            {
                                g.DrawPath(pen, graphicsPath);
                            }
                        }
                    }
                }
                else
                {
                    g.FillRectangle(linearGradientBrush, rect);
                    if (backColor.A > 80)
                    {
                        Rectangle rect2 = rect;
                        if (mode == LinearGradientMode.Vertical)
                        {
                            rect2.Height = (int)((float)rect2.Height * basePosition);
                        }
                        else
                        {
                            rect2.Width = (int)((float)rect.Width * basePosition);
                        }
                        using (SolidBrush solidBrush = new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
                        {
                            g.FillRectangle(solidBrush, rect2);
                        }
                    }
                    if (drawBorder)
                    {
                        using (Pen pen = new Pen(borderColor))
                        {
                            g.DrawRectangle(pen, rect);
                        }
                        rect.Inflate(-1, -1);
                        using (Pen pen = new Pen(innerBorderColor))
                        {
                            g.DrawRectangle(pen, rect);
                        }
                    }
                }
            }
        }

        protected Color GetColor(Color colorBase, int a, int r, int g, int b)
        {
            int a2 = (int)colorBase.A;
            int r2 = (int)colorBase.R;
            int g2 = (int)colorBase.G;
            int b2 = (int)colorBase.B;
            if (a + a2 > 255)
            {
                a = 255;
            }
            else
            {
                a = Math.Max(a + a2, 0);
            }
            if (r + r2 > 255)
            {
                r = 255;
            }
            else
            {
                r = Math.Max(r + r2, 0);
            }
            if (g + g2 > 255)
            {
                g = 255;
            }
            else
            {
                g = Math.Max(g + g2, 0);
            }
            if (b + b2 > 255)
            {
                b = 255;
            }
            else
            {
                b = Math.Max(b + b2, 0);
            }
            return Color.FromArgb(a, r, g, b);
        }

        protected static TextFormatFlags GetTextFormatFlags(ContentAlignment alignment, bool rightToleft)
        {
            TextFormatFlags textFormatFlags = TextFormatFlags.SingleLine | TextFormatFlags.WordBreak;
            if (rightToleft)
            {
                textFormatFlags |= (TextFormatFlags.Right | TextFormatFlags.RightToLeft);
            }
            if (alignment <= ContentAlignment.MiddleCenter)
            {
                switch (alignment)
                {
                    case ContentAlignment.TopLeft:
                        textFormatFlags = textFormatFlags;
                        break;
                    case ContentAlignment.TopCenter:
                        textFormatFlags |= TextFormatFlags.HorizontalCenter;
                        break;
                    case (ContentAlignment)3:
                        break;
                    case ContentAlignment.TopRight:
                        textFormatFlags |= TextFormatFlags.Right;
                        break;
                    default:
                        if (alignment != ContentAlignment.MiddleLeft)
                        {
                            if (alignment == ContentAlignment.MiddleCenter)
                            {
                                textFormatFlags |= (TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
                            }
                        }
                        else
                        {
                            textFormatFlags |= TextFormatFlags.VerticalCenter;
                        }
                        break;
                }
            }
            else if (alignment <= ContentAlignment.BottomLeft)
            {
                if (alignment != ContentAlignment.MiddleRight)
                {
                    if (alignment == ContentAlignment.BottomLeft)
                    {
                        textFormatFlags |= TextFormatFlags.Bottom;
                    }
                }
                else
                {
                    textFormatFlags |= (TextFormatFlags.Right | TextFormatFlags.VerticalCenter);
                }
            }
            else if (alignment != ContentAlignment.BottomCenter)
            {
                if (alignment == ContentAlignment.BottomRight)
                {
                    textFormatFlags |= (TextFormatFlags.Bottom | TextFormatFlags.Right);
                }
            }
            else
            {
                textFormatFlags |= (TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter);
            }
            return textFormatFlags;
        }

        protected virtual void CalculateRect(out Rectangle imageRect, out Rectangle textRect, ButtonEx button)
        {
            int num = 0;
            int num2 = 0;
            if (button.Image != null)
            {
                num = button.Image.Width;
                num2 = button.Image.Height;
            }
            imageRect = Rectangle.Empty;
            textRect = Rectangle.Empty;
            if (button.Image == null)
            {
                textRect = new Rectangle(2, 0, button.Width - 4, button.Height);
            }
            else
            {
                switch (button.TextImageRelation)
                {
                    case TextImageRelation.Overlay:
                        imageRect = new Rectangle(2, (button.Height - num2) / 2, num, num2);
                        textRect = new Rectangle(2, 0, button.Width - 4, button.Height);
                        break;
                    case TextImageRelation.ImageAboveText:
                        imageRect = new Rectangle((button.Width - num2) / 2, 2, num, num2);
                        textRect = new Rectangle(2, imageRect.Bottom, button.Width, button.Height - imageRect.Bottom - 2);
                        break;
                    case TextImageRelation.TextAboveImage:
                        imageRect = new Rectangle((button.Width - num) / 2, button.Height - num2 - 2, num, num2);
                        textRect = new Rectangle(0, 2, button.Width, button.Height - imageRect.Y - 2);
                        break;
                    case TextImageRelation.ImageBeforeText:
                        {
                            SizeF sizeF = TextRenderer.MeasureText(button.Text, button.Font);
                            int num3 = (int)sizeF.Width + num + 2;
                            int x = (button.Width - num3) / 2;
                            imageRect = new Rectangle(x, (button.Height - num2) / 2, num, num2);
                            textRect = new Rectangle(imageRect.Right + 2, 0, (int)sizeF.Width, button.Height);
                            break;
                        }
                    case TextImageRelation.TextBeforeImage:
                        imageRect = new Rectangle(button.Width - num - 2, (button.Height - num2) / 2, num, num2);
                        textRect = new Rectangle(2, 0, imageRect.X - 2, button.Height);
                        break;
                }
                if (button.RightToLeft == RightToLeft.Yes)
                {
                    imageRect.X = button.Width - imageRect.Right;
                    textRect.X = button.Width - textRect.Right;
                }
            }
        }

        protected void DrawGlass(Graphics g, RectangleF glassRect, int alphaCenter, int alphaSurround)
        {
            this.DrawGlass(g, glassRect, Color.White, alphaCenter, alphaSurround);
        }

        protected void DrawGlass(Graphics g, RectangleF glassRect, Color glassColor, int alphaCenter, int alphaSurround)
        {
            using (GraphicsPath graphicsPath = new GraphicsPath())
            {
                graphicsPath.AddEllipse(glassRect);
                using (PathGradientBrush pathGradientBrush = new PathGradientBrush(graphicsPath))
                {
                    pathGradientBrush.CenterColor = Color.FromArgb(alphaCenter, glassColor);
                    pathGradientBrush.SurroundColors = new Color[]
                    {
                        Color.FromArgb(alphaSurround, glassColor)
                    };
                    pathGradientBrush.CenterPoint = new PointF(glassRect.X + glassRect.Width / 2f, glassRect.Y + glassRect.Height / 2f);
                    g.FillPath(pathGradientBrush, graphicsPath);
                }
            }
        }

        private Color _DisableForeColor = ColorTranslator.FromHtml("#D4D0C8");
    }
}